package com.macaline.util;

import java.io.File;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;

import com.xnx3.ScanClassUtil;

public class ScanClassesUtil {
	

	/**
	 * 扫描有指定的注解的class类
	 * @author warm_joy 
	 * @param list 需要扫描的class列表
	 * @param annotations 需要扫描的注解
	 * @return 
	 */
	public static List<Class<?>>  getClassSearchAnnotationsName(List<Class<?>> list, List<String> annotations) {
		// 用于保存结果的list
		List<Class<?>> classList = new LinkedList<Class<?>>();
		// 循环遍历注解列表
		Iterator<String> iterator = annotations.iterator();
		String annotation = null;
		List<Class<?>> sreachList = null;
		while (iterator.hasNext()) {
			annotation = iterator.next();
			// 对当前遍历的注解进行扫描
			sreachList = ScanClassUtil.getClassSearchAnnotationsName(list, annotation);
			// 对扫描结果进行保存
			classList.addAll(sreachList);
		}
		return classList;
	}
	
	/**
	 * 扫描多个包下的class类 例：扫描com.scan1和com.scan2包下的所有类
	 * 那么packageName参数为：com，fileList参数为列表内容为scan1 和 scan2
	 * 
	 * @author warm_joy
	 * @param fileList    需要扫描的文件夹列表
	 * @param packageName 文件夹表示包的父包
	 * @param isRecursive 是否递归扫描 true：进行递归扫描，否则反之。
	 * @return
	 * @throws ClassNotFoundException
	 */
	public static List<Class<?>> getPluginClassList(List<String> fileList, String packageName, boolean isRecursive)
			throws ClassNotFoundException {
		List<Class<?>> classList = new LinkedList<Class<?>>();
		// 循环遍历文件夹
		Iterator<String> iterator = fileList.iterator();
		String scanPackage = null;
		while (iterator.hasNext()) {
			File file = new File(iterator.next());
			// 拼装进行扫面的报名
			scanPackage = packageName + "." + file.getName();
			// 扫描class类型
			List<Class<?>> classes = getclassInFile(scanPackage, isRecursive);
			// 保存扫描结果
			classList.addAll(classes);
		}
		return classList;
	}

	/**
	 * 扫描某个包下的class类型
	 * 
	 * @author warm_joy
	 * @param scanPackage 扫描的报名
	 * @param isRecursive 是否递归扫描 true：进行递归扫描，否则反之。
	 * @return 该报名下扫描的实体类
	 * @throws ClassNotFoundException
	 */
	public static List<Class<?>> getclassInFile(String scanPackage, boolean isRecursive) throws ClassNotFoundException {
		List<Class<?>> classList = new LinkedList<Class<?>>();
		// 当前正在遍历的包的路径名称
		String recuPackagePaht = scanPackage;
		// 获得要扫描的包的路径
		String packageDirPath = scanPackage.replace(".", File.separator);
		// 获取该包名的物理路径
		String path = ClassLoader.getSystemResource(packageDirPath).getPath();
		File file = new File(path);
		// 获取当前目录下的子文件
		List<File> list = Arrays.asList(file.listFiles());
		// 循环遍历子文件
		Iterator<File> iterator = list.iterator();
		while (iterator.hasNext()) {
			File childFile = iterator.next();
			// 如果该文件是一个文件的情况下
			if (childFile.isFile()) {
				// 确保该文件为可加载的class文件
				if (childFile.getName().endsWith(".class") == true) {
					// 获取该文件对应的class名称
					String className = recuPackagePaht + "."
							+ childFile.getName().substring(0, childFile.getName().length() - 6);
					// 通过类加载器获得class对象
					Class<?> clazz = Class.forName(className);
					// 保存class对象
					classList.add(clazz);
				}
			}
			// 如果该文件是一个文件件并且进行递归扫描
			else if (isRecursive == true && childFile.isDirectory()) {
				// 获得这个子文件的报名
				String classPackageName = recuPackagePaht + "." + childFile.getName();
				// 再次使用该方法进行递归
				List<Class<?>> getclassInFile = getclassInFile(classPackageName, isRecursive);
				// 将扫描的返回添加到list中
				classList.addAll(getclassInFile);
			}
		}
		return classList;
	}

	/**
	 * 查询class是否有指定的注解
	 * @author warm_joy
	 * @param clazz                查询的类名
	 * @param AnnotationSimpleName 查找的简单名称注解简易名称
	 * @return true:该类有该注解，否则反之。
	 */
	public static boolean clazzIsAnnotation(Class<?> clazz, String AnnotationSimpleName) {
		// 获取该类上的所有的注解信息
		Annotation[] annotations = clazz.getAnnotations();
		String annoName = null;
		// 循环遍历注解列表
		for (Annotation annotation : annotations) {
			// 得到当前遍历的注解的名称
			annoName = annotation.annotationType().getSimpleName();
			// 判断是否与要查找的注解的名称一致
			if (annoName.equals(AnnotationSimpleName) == true) {
				return true;
			}
		}
		return false;
	}

	public static void main(String[] args) throws ClassNotFoundException {
		List<String> fileList = new ArrayList<>();
		System.out.println(fileList instanceof RandomAccess);
	}

}
